#include "cc_math_tool.h"
#include <algorithm>
#include <cmath>
#include <iostream>


float sigmoid(float x) { return (1.0 / (1.0 + exp(-x))); }
float inverse_sigmoid(float x) { return log(x / (1 - x)); }
static float get_iou_value(ccbox rect1, ccbox rect2) {
  int xx1, yy1, xx2, yy2;

  xx1 = std::max(rect1.x, rect2.x);
  yy1 = std::max(rect1.y, rect2.y);
  xx2 = std::min(rect1.x + rect1.width - 1, rect2.x + rect2.width - 1);
  yy2 = std::min(rect1.y + rect1.height - 1, rect2.y + rect2.height - 1);

  int insection_width, insection_height;
  insection_width = std::max(0, xx2 - xx1 + 1);
  insection_height = std::max(0, yy2 - yy1 + 1);

  float insection_area, union_area, iou;
  insection_area = float(insection_width) * insection_height;
  union_area = float(rect1.width * rect1.height + rect2.width * rect2.height -
                     insection_area);
  iou = insection_area / union_area;
  return iou;
}

static bool cmp_max(std::pair<int, CcObjBBox> &x,
                    std::pair<int, CcObjBBox> &y) {
  return x.second.score > y.second.score;
}
std::vector<int> nms(const std::vector<CcObjBBox> &int_bbox,
                     float iou_threshold, int class_num) {

  std::vector<std::vector<std::pair<int, CcObjBBox>>> bbox_class;

  bool class_num_flag = false;
  if (class_num == 5) {
    class_num_flag = true;
    class_num = 2; //类别个数,行人电动车归为1类. 小轿车、公交车、大卡车归为1类
  }

  bbox_class.resize(class_num);
  for (uint32_t i = 0; i < int_bbox.size(); i++) {
    auto &b = int_bbox[i];
    if ((b.label == 3 || b.label == 4) &&
        class_num_flag) // 3行人类别
                        // 4电动车类别,只有传入的类别数为5是才将行人和电动车归为一类
    {
      bbox_class[1].push_back(std::pair<int, CcObjBBox>(i, b));
    } else {
      bbox_class[0].push_back(std::pair<int, CcObjBBox>(i, b));
    }
  }
  std::vector<int> out_index;
  // std::cout<<"-----------------"<<std::endl;
  for (auto &bbox : bbox_class) {
    std::sort(bbox.begin(), bbox.end(), cmp_max);
    int i = 0;
    std::vector<int> indices;
    for (auto &obj : bbox) {
      const int idx = i;
      bool keep = true;
      for (unsigned k = 0; k < indices.size(); ++k) {
        if (keep) {
          const int kept_idx = indices[k];
          float overlap =
              get_iou_value(obj.second.bbox, bbox[kept_idx].second.bbox);

          keep = overlap < iou_threshold;
        } else {
          break;
        }
      }
      if (keep) {
        indices.push_back(idx);
        out_index.push_back(obj.first);
        // std::cout<<obj.first<<std::endl;
      }
      i++;
    }
  }
  return out_index;
}
